namespace Isolation.TeamFoundationServer
{
	#region #using Directives

	using System;
	using System.Collections.Generic;
	using System.Linq;

	using Microsoft.TeamFoundation.WorkItemTracking.Client;

	#endregion

	internal class TfsWorkItemStore : ITfsWorkItemStore
	{
		private readonly WorkItemStore workItemStore;

		public TfsWorkItemStore(WorkItemStore workItemStore)
		{
			this.workItemStore = workItemStore;
		}

		#region Implementation of ITfsWorkItemStore

		public WorkItemStore TfsStore
		{
			get { return this.workItemStore; }
		}

		public string[] Projects
		{
			get
			{
				try
				{
					return this.workItemStore.Projects.Cast<Project>().Select(x => x.Name).ToArray();
				}
				catch (ConnectionException e)
				{
					throw new TfsConnectionException(e);
				}
			}
		}

		public string GetIterationName(string projectName, int iterationId)
		{
			try
			{
				var project = this.workItemStore.Projects[projectName];
				var iterationNode = project.FindNodeInSubTree(iterationId);
				return iterationNode.Name;
			}
			catch (ConnectionException e)
			{
				throw new TfsConnectionException(e);
			}
		}

		public string GetIterationName(string projectName, string iterationPath)
		{
			try
			{
				var project = this.workItemStore.Projects[projectName];
				var iterationNode = project.FindNodeInSubTree(iterationPath.Substring(iterationPath.IndexOf('\\') + 1), Node.TreeType.Iteration);
				return iterationNode.Name;
			}
			catch (ConnectionException e)
			{
				throw new TfsConnectionException(e);
			}
		}

		public string GetQueryString(string projectName, string iterationPath, string workItemTypeNames)
		{
			// TODO: take in a parameter with a list of all the custom fields that will be queried, so no
			// additional roundtrip is necessary
			string fields = string.Format("[{0}], [{1}], [{2}], [{3}], [{4}], [{5}], [{6}]", CoreFieldReferenceNames.Id, CoreFieldReferenceNames.WorkItemType,
			                              CoreFieldReferenceNames.AssignedTo, CoreFieldReferenceNames.Title, CoreFieldReferenceNames.ChangedBy,
			                              CoreFieldReferenceNames.ChangedDate, CoreFieldReferenceNames.WorkItemType);

			string tfsQueryString = string.Format(@"SELECT {0} FROM WorkItems " + "WHERE [{1}] = '{2}' AND [{3}] in ({4}) AND [{5}] UNDER '{6}' ORDER BY [{7}]",
			                                      fields, CoreFieldReferenceNames.TeamProject, projectName, CoreFieldReferenceNames.WorkItemType,
			                                      workItemTypeNames, CoreFieldReferenceNames.IterationPath, iterationPath, CoreFieldReferenceNames.Id);

			return tfsQueryString;
		}

		public ICollection<IWorkItem> Query(string wiql)
		{
			try
			{
				var workItemCollection = this.workItemStore.Query(wiql);
				var workItemList = new List<IWorkItem>(workItemCollection.Count);

				foreach (Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItem workItem in workItemCollection)
				{
					workItemList.Add(new WorkItem(workItem));
				}

				return workItemList;
			}
			catch (ConnectionException ce)
			{
				throw new TfsConnectionException(ce);
			}
		}

		public IWorkItem GetWorkItem(int workItemId, DateTime at)
		{
			try
			{
				return new WorkItem(this.workItemStore.GetWorkItem(workItemId, at));
			}
			catch (DeniedOrNotExistException)
			{
				return null;
			}
			catch (ConnectionException e)
			{
				throw new TfsConnectionException(e);
			}
		}

		public string GetQueryString(string projectName, int iterationId, string workItemTypeNames)
		{
			string fields = string.Format("[{0}], [{1}], [{2}], [{3}], [{4}], [{5}], [{6}]", CoreFieldReferenceNames.Id, CoreFieldReferenceNames.WorkItemType,
			                              CoreFieldReferenceNames.AssignedTo, CoreFieldReferenceNames.Title, CoreFieldReferenceNames.ChangedBy,
			                              CoreFieldReferenceNames.ChangedDate, CoreFieldReferenceNames.WorkItemType);

			string tfsQueryString = string.Format(@"SELECT {0} FROM WorkItems " + "WHERE [{1}] = '{2}' AND [{3}] in ({4}) AND [{5}] = '{6}' ORDER BY [{7}]",
			                                      fields, CoreFieldReferenceNames.TeamProject, projectName, CoreFieldReferenceNames.WorkItemType,
			                                      workItemTypeNames, CoreFieldReferenceNames.IterationId, iterationId, CoreFieldReferenceNames.Id);
			return tfsQueryString;
		}

		#endregion
	}
}